#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include "utils/pg_lsn.h"
#include "storage/relfilenode.h"

typedef struct  
{
    uint8_t *buf;
    size_t count;
    size_t cap;
} Bufrd;

typedef struct  
{
    int64_t fd;
    int32_t error;

} IOResult;

typedef struct XLogKey
{
	// uint32_t timeLine;
	uint64_t	lsn;
} XLogKey;


typedef struct XLogItem
{
	XLogKey xlogKey;
	char *begin;
	int length;
	struct XLogItem *next;
} XLogItem;

typedef struct PageKey
{
    RelFileNode relfileNode;
    uint32      forkNo;
    uint32      blkNo;
    uint64      pageLsn;
    uint64      replyLsn;
} PageKey;



extern IOResult openfs(const char *pathname, int flags);

extern int closefs(int64_t fd);

extern int64_t lseekfs(int64_t fd, int64_t offset, int32_t whence);

extern int64_t truncatefs(int64_t fd, uint64_t offset);

extern int writefs(int64_t fd, const void *buf, size_t count, int64_t offset);

extern Bufrd dataRead(int64_t fd,
                      int64_t offset,
                      int64_t lastLsn,
                      uint32_t dbid,
                      uint32_t relid,
                      uint32_t segno,
                      uint32_t forkno);

extern void free_dataRead(uint8_t *buf, size_t count, size_t cap);

extern Bufrd readfs(int64_t fd, int64_t offset, uint32_t size);
extern int batchRead(uint8_t *buf, uint32_t timeline, uint64_t startPtr,uint64_t endPtr, bool needStore);
extern int batchReadForTools(uint8_t *buf, uint32_t timeline, uint64_t startPtr,uint64_t endPtr, bool needStore);
extern uint8_t kvwrite(XLogItem *xlogItem);
extern uint8_t flushwals(XLogItem *xlogItem, uint32_t timeline);
extern uint8_t kvflush(XLogRecPtr lsn);
extern Bufrd ReadWalsByPage(uint32_t dbid,
                      uint32_t relid,
                      uint32_t forkno,
                      uint32_t blkno,
                      uint32_t timeline,
                      LsnNode* lsnhead);
extern void InsertConsistToKV(uint64_t lsn);
extern uint64_t GetConsistLsn(uint64_t lsn);
extern void DelConsistLsns(uint64_t lsn);
extern void DelRangeWals(uint32_t timeline, uint64_t startPtr,uint64_t endPtr);
//extern void ReceivePageFromDataBuffer(PageKey *pk, uint8_t *buffer);  //when evict one page out databuffer, we should call this to store the page.
extern uint8_t EvictOnePageOutOfMemory(PageKey pageKey, char *value);

//GetPageFromCurrentNode(PageKey *pk);
extern Bufrd MoveOnePageToMemory(PageKey pageKey);

//extern Bufrd GetWalsFromDisk(PageKey pageKey);


extern void RemoveBufferFromLocal(uint32_t dbid, uint32_t relid, uint32_t forkno, uint32_t blkno);
